package core.helpers;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import core.Pilot;

/**
 * Class provides the methods for working with dates and times
 */
public class DateHelper
{
	protected static Pilot pilot;

	/**
	 * Constructor
	 * @param p_pilot
	 */
	public DateHelper(Pilot p_pilot)
	{
		pilot = p_pilot;
	}

	/**
	 * Gets the current date in the custom format p_dateFormat
	 * @param p_dateFormat
	 * @param p_timeZone
	 * @return Current date
	 */
	public static String getCurrentDate(String p_dateFormat, String p_timeZone)
	{
		try
		{
			Date date = new Date();
			DateFormat dateFormat = new SimpleDateFormat(p_dateFormat);
			dateFormat.setTimeZone(TimeZone.getTimeZone(p_timeZone));
			String currentDate = dateFormat.format(date);
			pilot.log().debug("Get the current date [" + p_dateFormat + "; " + p_timeZone + "] => " + currentDate);

			return currentDate;
		}
		catch (Exception p_exception)
		{
			pilot.log().warn("Cannot get the current date [" + p_dateFormat + "; " + p_timeZone + "]\nError: " + p_exception);

			return null;
		}

	}

	/**
	 * Gets the current date in the format p_dateFormat with system time zone
	 * @param p_dateFormat
	 * @return Current date
	 */
	public String getCurrentDate(String p_dateFormat)
	{
		try
		{
			Date date = new Date();
			DateFormat dateFormat = new SimpleDateFormat(p_dateFormat);
			dateFormat.setTimeZone(Calendar.getInstance().getTimeZone());
			String currentDate = dateFormat.format(date);
			pilot.log().debug("Get the current date [" + p_dateFormat + "] => " + currentDate);

			return currentDate;
		}
		catch (Exception p_exception)
		{
			pilot.log().warn("Cannot get the current date [" + p_dateFormat + "]\nError: " + p_exception);

			return null;
		}
	}

	/**
	 * Gets current time in milliseconds
	 * @return Time in milliseconds
	 */
	public long getCurrentTimeInMilliseconds()
	{
		long currentTimne = System.currentTimeMillis();
		pilot.log().debug("Get current time in milliseconds => " + currentTimne);

		return currentTimne;
	}

	/**
	 * Converts date from String to java.util.Date
	 * @param p_dateString
	 * @param p_dateFormat
	 * @return Converted date
	 */
	public Date convertStringToDate(String p_dateString, String p_dateFormat)
	{
		try
		{
			Date date = new SimpleDateFormat(p_dateFormat).parse(p_dateString);
			pilot.log().debug("Convert date from String to java.util.Date [" + p_dateString + "; " + p_dateFormat + "] => " + date);

			return date;
		}
		catch (Exception p_exception)
		{
			pilot.log().warn("Cannot convert date from String to java.util.Date [" + p_dateString + "; " + p_dateFormat + "]\nError: " + p_exception);

			return null;
		}
	}

	/**
	 * Adds a day(s) to a date
	 * @param p_date
	 * @param p_daysCount
	 * @param p_dateFormat
	 * @return New date
	 */
	public String addDaysToDate(Date p_date, int p_daysCount, String p_dateFormat)
	{
		try
		{
			long milliseconds = p_daysCount * 86400000;
			long time = p_date.getTime();
			time += milliseconds;
			Date date = new Date(time);
			SimpleDateFormat dateFormat = new SimpleDateFormat(p_dateFormat);
			String newDate = dateFormat.format(date);

			pilot.log().debug("Add days to the date [" + p_daysCount + "; " + p_daysCount + "; " + p_dateFormat + "] => " + newDate);

			return newDate;
		}
		catch (Exception p_exception)
		{
			pilot.log().warn("Cannot add days to the date [" + p_daysCount + "; " + p_daysCount + "; " + p_dateFormat + "]\nError: " + p_exception);

			return null;
		}
	}

	/**
	 * Gets current time in the format p_timeFormat
	 * @param p_timeFormat
	 * @return Current time
	 */
	public String getCurrentTime(String p_timeFormat)
	{
		try
		{
			Date date = new Date();
			DateFormat df = new SimpleDateFormat("HH:mm:ss yyyy/MM/dd");
			DateFormat time = new SimpleDateFormat(p_timeFormat);
			df.setTimeZone(TimeZone.getTimeZone("Europe/Kiev"));
			String currentTime = time.format(date);

			pilot.log().debug("Get current time [" + p_timeFormat + "] => " + currentTime);

			return currentTime;
		}

		catch (Exception p_exception)
		{
			pilot.log().warn("Cannot get current time [" + p_timeFormat + "]\nError: " + p_exception);

			return null;
		}

	}

	/**
	 * Gets a month name by his number
	 * @param p_monthNumber
	 * @return Month name
	 */
	public String getMonthNameByNumber(int p_monthNumber)
	{
		try
		{
			p_monthNumber = p_monthNumber - 1; // for normal counting starts from 1 not zero
			String[] monthNames = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
			pilot.log().debug("Get month name by number current time [" + p_monthNumber + "] => " + monthNames[p_monthNumber]);

			return monthNames[p_monthNumber];
		}
		catch (Exception p_exception)
		{
			pilot.log().warn("Cannot get month name by number [" + p_monthNumber + "]\nError: " + p_exception);

			return null;
		}

	}

	/**
	 * Gets a month number by his name
	 * @param p_monthName
	 * @return Month number
	 */
	public Integer getMonthNumberByName(String p_monthName)
	{
		try
		{
			Integer monthNumber = 0;
			String[] monthNames = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };

			for (String monthName : monthNames)
			{
				if (monthName.equals(p_monthName))
				{
					return monthNumber;
				}

				monthNumber++;
			}

			pilot.log().warn("Get month number by name [" + p_monthName + "] => " + monthNumber);

			return monthNumber;
		}
		catch (Exception p_exception)
		{
			pilot.log().warn("Cannot get month number by name [" + p_monthName + "]\nError: " + p_exception);

			return null;
		}
	}
}